#include "defs.h"
#include "mysocket.h"
#include "Player.h"

typedef struct {
	int pair[2];
} pairType;

void Run();
void sendResults();
void ReadParameters(int argc, char *argv[]);
void AcceptConnections();
void runGame();
void cleanUp();

//void createPrefOrder(int index);
void loadGame(char *fname);
void sendGame(Player *player);
//void sendGameMatlab(Player *player);

int iteraciones = -1, samplitos = 1;
double errorRate;

int Payoffs[4][4][2];
//int Prefs[4][4][2];
int numActions;
Player *rowPlayer/* = new Player()*/, *colPlayer/* = new Player()*/;
char gameName[1024];
//bool rowmatlab = false, colmatlab = false;

FILE *fpLog = NULL;

/* *****************************************************
* 
* Server.exe game=[filename] iters=[num] samps=[num] log=[filename]
*
******************************************************** */
void main(int argc, char *argv[]) {
	srand(time(NULL));
	// Read Parameters
	ReadParameters(argc, argv);

	// Accept connections
	AcceptConnections();

	// Play the Game
	runGame();

	Sleep(1050);

	cleanUp();

	printf("press any key to continue ... ");
	getch();
}

void runGame() {
	int i;
	int samecount = 0;
	int total[2] = {0, 0};

	//FILE *fp = fopen("results.txt", "w");
	//fprintf(fp, "%s vs. %s in %s\n", rowPlayer->nombre, colPlayer->nombre, gameName);
	//fflush(fp);

	for (i = 0; i < iteraciones; i++) {
		if ((i % 5000) == 0)
			printf("%i\n", i);
		// read actions and move
		rowPlayer->getAction();
		colPlayer->getAction();

		if (rowPlayer->action == colPlayer->action)
			samecount ++;

		rowPlayer->move(-1);//errorRate);
		colPlayer->move(-1);//errorRate);

		//fprintf(fp, "%i: intended: (%i, %i); actual: (%i, %i); payoffs: (%i, %i)\n", i, rowPlayer->intendedAction, colPlayer->intendedAction,
		//	rowPlayer->action, colPlayer->action, Payoffs[rowPlayer->action][colPlayer->action][0], Payoffs[rowPlayer->action][colPlayer->action][1]);
		//fflush(fp);

		total[0] += Payoffs[rowPlayer->action][colPlayer->action][0];
		total[1] += Payoffs[rowPlayer->action][colPlayer->action][1];

		sendResults();
	}

	Sleep(50);

//	if (rowPlayer->matlab)
///		rowPlayer->sox->sendmsg(-1);
//	else
		rowPlayer->sox->SendMessage("Done\n", (int)strlen("Done\n"));

//	if (colPlayer->matlab)
//		colPlayer->sox->sendmsg(-1);
//	else
		colPlayer->sox->SendMessage("Done\n", (int)strlen("Done\n"));

	//fprintf(fp, "Average Averages: (%.3lf, %.3lf)\n", total[0] / (double)iteraciones, total[1] / (double)iteraciones);
	//fflush(fp);
	printf("Average Averages: (%s = %.3lf, %s = %.3lf)\n", rowPlayer->nombre, total[0] / (double)iteraciones, 
														colPlayer->nombre, total[1] / (double)iteraciones);

	if (fpLog != NULL) {
		fprintf(fpLog, "%s = %lf, %s = %lf\n", rowPlayer->nombre, total[0] / (double)iteraciones, colPlayer->nombre, total[1] / (double)iteraciones);
		fflush(fpLog);
	}

	//fclose(fp);
}

void sendResults() {
	//if (rowPlayer->matlab) {
	//	rowPlayer->sox->sendmsg(rowPlayer->action);
	//	rowPlayer->sox->sendmsg(colPlayer->action);
	//}
	//else {
		char mensaje[1024];
		sprintf(mensaje, "%i\n%i\n", rowPlayer->action, colPlayer->action);
		//printf(mensaje);
		rowPlayer->sox->SendMessage(mensaje, (int)strlen(mensaje));
	//}

	//if (colPlayer->matlab) {
	//	colPlayer->sox->sendmsg(colPlayer->action);
	//	colPlayer->sox->sendmsg(rowPlayer->action);
	//}
	//else {
		//char mensaje[1024];
		sprintf(mensaje, "%i\n%i\n", colPlayer->action, rowPlayer->action);
		colPlayer->sox->SendMessage(mensaje, (int)strlen(mensaje));
	//}
}

void ReadParameters(int argc, char *argv[]) {
	int i;

	for (i = 1; i < argc; i++) {
		if (!strncmp(argv[i], "game", 4)) {
			loadGame(argv[i]+5);
		}
		else if (!strncmp(argv[i], "iters", 5)) {
			iteraciones = atoi(argv[i]+6);
		}
		else if (!strncmp(argv[i], "samps", 5)) {
			samplitos = atoi(argv[i]+6);
		}
		else if (!strncmp(argv[i], "acc", 3)) {
			errorRate = atof(argv[i]+4);
			printf("errorRate = %lf\n", errorRate);
		}
		else if (!strncmp(argv[i], "log", 3)) {
			char filename[1024];
			sprintf(filename, "results\\%s.txt\0", argv[i]+4);
			printf("log to %s\n", filename);
			fpLog = fopen(filename, "a+");
		}
	}
}

void AcceptConnections() {
	MySocket *home;
	int count = 3000;
	char portmsg[1024], buf[1024];

	home = new MySocket(count);
	count ++;
	
	home->AcceptEm();
	
	home->ReadMessage(buf);
	bool both = false;
	for (int i = 0; i < 20; i++) {
		//printf("%c ", buf[i]);
		if ((i > 0) && (buf[i] != '\0'))
			both = true;
	}
	//printf("\n");
/*	if (buf[0] == 24) {
		rowmatlab = true;
		if (!both)
			home->ReadMessage(buf);
		home->sendmsg(count);
		rowPlayer->setUpMatlabConnection(count);
		sendGameMatlab(rowPlayer);
	}
	else {*/
		sprintf(portmsg, "%i\n\0", count);
		home->SendMessage(portmsg, (int)strlen(portmsg));
		rowPlayer->setUpConnection(count);
		sendGame(rowPlayer);
		printf("row player done\n");
//	}
	count ++;

	home->AcceptEm();
	home->ReadMessage(buf);
	both = false;
	for (int i = 0; i < 20; i++) {
		//printf("%c ", buf[i]);
		if ((i > 0) && (buf[i] != '\0'))
			both = true;
	}
	//printf("\n");
/*	if (buf[0] == 24) {
		colmatlab = true;
		if (!both)
			home->ReadMessage(buf);
		home->sendmsg(count);
		colPlayer->setUpMatlabConnection(count);
		sendGameMatlab(colPlayer);
	}*/
//	else {
		sprintf(portmsg, "%i\n\0", count);
		home->SendMessage(portmsg, (int)strlen(portmsg));
		colPlayer->setUpConnection(count);
		sendGame(colPlayer);
		printf("column player done\n");
//	}
	//home->AcceptEm();
	//sprintf(portmsg, "%i\n\0", count);
	//home->SendMessage(portmsg, (int)strlen(portmsg));
	//colPlayer->setUpConnection(count);
	//sendGame(colPlayer);

	//delete home;


	if ((rowPlayer->type == COL) || (colPlayer->type == ROW)) {
		printf("switching player order because connection didn't happen in the right order\n");
		Player *tmpPlayer = rowPlayer;
		rowPlayer = colPlayer;
		colPlayer = tmpPlayer;
	}

	if ((rowPlayer->type == COL) || (colPlayer->type == ROW)) {
		printf("Row and column player didn't connect\n");
		exit(1);
	}
}

void cleanUp() {
	if (fpLog != NULL)
		fclose(fpLog);
//	delete rowPlayer;
//	delete colPlayer;
}

void loadGame(char *fname) {
	strcpy(gameName, fname);
	char fnombre[1024];
	sprintf(fnombre, "..//games//%s.txt", fname);
	FILE *fp = fopen(fnombre, "r");
	if (fp == NULL) {
		sprintf(fnombre, "..//..//games//%s.txt", fname);
		fp = fopen(fnombre, "r");
		if (fp == NULL) {
			sprintf(fnombre, "games//%s.txt", fname);
			fp = fopen(fnombre, "r");
			if (fp == NULL) {
				printf("game file not found\n");
				exit(1);
			}
		}
	}

	fscanf(fp, "%i", &numActions);
	rowPlayer = new Player(numActions);
	colPlayer = new Player(numActions);
//	printf("numActions = %i\n", numActions);
	int row, col;

	for (col = 0; col < numActions; col++) {
		for (row = 0; row < numActions; row++) {
			fscanf(fp, "%i %i", &(Payoffs[row][col][0]), &(Payoffs[row][col][1]));
		}
	}

	fclose(fp);

	//createPrefOrder(0);
	//createPrefOrder(1);
}
/*
void createPrefOrder(int index) {
	// create preferences
	int list[16][3];
	int count = 0, col, row;
	for (col = 0; col < numActions; col++) {
		for (row = 0; row < numActions; row++) {
			list[count][0] = row;
			list[count][1] = col;
			list[count][2] = Payoffs[row][col][index];
			count ++;
		}
	}

	int i, j;
	int tmp[3];
	for (i = 0; i < count; i++) {
		for (j = 0; j < count-1; j++) {
			if (list[j][2] < list[j+1][2]) {
				tmp[0] = list[j][0];
				tmp[1] = list[j][1];
				tmp[2] = list[j][2];
				list[j][0] = list[j+1][0];
				list[j][1] = list[j+1][1];
				list[j][2] = list[j+1][2];
				list[j+1][0] = tmp[0];
				list[j+1][1] = tmp[1];
				list[j+1][2] = tmp[2];
			}
		}
	}

	int current = 1;
	for (i = 0; i < count; i++) {
		Prefs[list[i][0]][list[i][1]][index] = current;

		if (i < (count-1)) {
			//if (Prefs[list[i+1][0]][list[i+1][1]][index] != Prefs[list[i][0]][list[i][1]][index])
			//	current = i+2;
			if (list[i][2] != list[i+1][2])
				current = i+2;
		}
	}
}
*/
void sendGame(Player *player) {
	char gameInfo[1024];

	// number of actions
	sprintf(gameInfo, "%i\n\0", numActions);

	int row, col;
	if (player->type == ROW) {
		for (row = 0; row < numActions; row ++) {
			for (col = 0; col < numActions; col ++) {
				// everyone thinks they are the row player
				sprintf(gameInfo, "%s%i\n", gameInfo, Payoffs[row][col][0]);
			}
		}
	}
	else {
		for (col = 0; col < numActions; col ++) {
			for (row = 0; row < numActions; row ++) {
				// everyone thinks they are the row player
				sprintf(gameInfo, "%s%i\n", gameInfo, Payoffs[row][col][1]);
			}
		}
	}

/*	// sending the pref orders (but just payoffs right now)
	if (player->type == ROW) {
		for (row = 0; row < numActions; row ++) {
			for (col = 0; col < numActions; col ++) {
				// everyone thinks they are the row player
				sprintf(gameInfo, "%s%i\n", gameInfo, Prefs[row][col][1]);
			}
		}
	}
	else {
		for (col = 0; col < numActions; col ++) {
			for (row = 0; row < numActions; row ++) {
				// everyone thinks they are the row player
				sprintf(gameInfo, "%s%i\n", gameInfo, Prefs[row][col][0]);
			}
		}
	}*/
	sprintf(gameInfo, "%s\0", gameInfo);

	player->sox->SendMessage(gameInfo, (int)strlen(gameInfo));
}
/*
void sendGameMatlab(Player *player) {
	player->sox->sendmsg(numActions);

	int row, col;
	if (player->type == ROW) {
		for (row = 0; row < numActions; row ++) {
			for (col = 0; col < numActions; col ++) {
				// everyone thinks they are the row player
				player->sox->sendmsg(Payoffs[row][col][0]);
			}
		}
	}
	else {
		for (col = 0; col < numActions; col ++) {
			for (row = 0; row < numActions; row ++) {
				// everyone thinks they are the row player
				player->sox->sendmsg(Payoffs[row][col][1]);
			}
		}
	}

	// sending the pref orders (but just payoffs right now)
	if (player->type == ROW) {
		for (row = 0; row < numActions; row ++) {
			for (col = 0; col < numActions; col ++) {
				// everyone thinks they are the row player
				player->sox->sendmsg(Prefs[row][col][1]);
				//player->sox->sendmsg(Payoffs[row][col][1]);
			}
		}
	}
	else {
		for (col = 0; col < numActions; col ++) {
			for (row = 0; row < numActions; row ++) {
				// everyone thinks they are the row player
				player->sox->sendmsg(Prefs[row][col][0]);
				//player->sox->sendmsg(Payoffs[row][col][0]);
			}
		}
	}
}
*/